﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Web.Caching;

namespace WebCacheHelper
{
	/// <summary>
	/// Offers static members for cache-enhanced versions of common file operations.
	/// </summary>
	public class FileCache
	{
		/// <summary>
		/// The length of time to keep cached copies of files in memory.  The default is 1 hour to help prevent excessive memory usage.
		/// </summary>
		public static TimeSpan Duration = new TimeSpan(1, 0, 0);

		/// <summary>
		/// Calls System.Web.Hosting.HostingEnvironment.MapPath and caches the result.  MapPath is a moderately expensive operation so a cache is helpful here.
		/// </summary>
		/// <param name="relativePath"></param>
		/// <returns></returns>
		public static string MapPath(string relativePath)
		{
			string name = "MapPath_" + relativePath;
			object o = HttpRuntime.Cache[name];

			if (o != null && o is string)
			{
				return (string)o;
			}
			else
			{
				string mappedPath = System.Web.Hosting.HostingEnvironment.MapPath(relativePath);
				HttpRuntime.Cache.Insert(name, mappedPath, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
				return mappedPath;
			}
		}

		/// <summary>
		/// Calls System.IO.File.ReadAllText and caches the result, along with a CacheDependency to detect file changes and keep the cache up to date.
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public static string ReadAllText(string path)
		{
			string name = "ReadAllText_" + path;
			object o = HttpRuntime.Cache[name];

			if (o != null && o is string)
			{
				return (string)o;
			}
			else
			{
				string text = File.ReadAllText(path);
				CacheDependency dependency = new CacheDependency(path);
				HttpRuntime.Cache.Insert(name, text, dependency, Cache.NoAbsoluteExpiration, Duration, System.Web.Caching.CacheItemPriority.Low, null);
				return text;
			}
		}

		/// <summary>
		/// Calls WebCacheHelper.MapPath followed by WebCacheHelper.ReadAllText.
		/// </summary>
		/// <param name="relativePath"></param>
		/// <returns></returns>
		public static string ReadAllTextRelative(string relativePath)
		{
			return ReadAllText(MapPath(relativePath));
		}

		/// <summary>
		/// Calls System.IO.File.ReadAllLines and caches the result, along with a CacheDependency to detect file changes and keep the cache up to date.
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public static string[] ReadAllLines(string path)
		{
			string name = "ReadAllLines_" + path;
			object o = HttpRuntime.Cache[name];

			if (o != null && o is string[])
			{
				return (string[])o;
			}
			else
			{
				string[] lines = File.ReadAllLines(path);
				CacheDependency dependency = new CacheDependency(path);
				HttpRuntime.Cache.Insert(name, lines, dependency, Cache.NoAbsoluteExpiration, Duration, System.Web.Caching.CacheItemPriority.Low, null);
				return lines;
			}
		}

		/// <summary>
		/// Calls WebCacheHelper.MapPath followed by WebCacheHelper.ReadAllLines.
		/// </summary>
		/// <param name="relativePath"></param>
		/// <returns></returns>
		public static string[] ReadAllLinesRelative(string relativePath)
		{
			return ReadAllLines(MapPath(relativePath));
		}

	}
}
